// 方式一 时间戳
// 第一次立即触发 最后不触发
let throttle = function (func, wait) {
  let context, args
  // 之前时间戳
  let previous = 0
  return function () {
    context = this
    args = arguments
    // 当前时间戳
    let current = Date.now()
    if (current - previous > wait) {
      func.apply(context, args)
      previous = current
    }
  }
}




// 方式二 定时器
// 第一次不触发 最后触发
let throttle1 = function (func, wait) {
  let context, args, timeout
  return function () {
    context = this
    args = arguments
    if (!timeout) {
      timeout = setTimeout(() => {
        timeout = null
        func.apply(context, args)
      }, wait);
    }
  }
}




// 方式三 结合使用
// 第一次触发 最后也触发
let throttle2 = function (func, wait) {
  let context, args, timeout
  let previous = 0   // 时间戳
  return function () {
    context = this
    args = arguments
    let current = Date.now()
    if (current - previous > wait) {
      if (timeout) {
        clearTimeout(timeout)
        timeout = null
      }
      func.apply(context, args)
      previous = current
    } else if (!timeout) {
      timeout = setTimeout(() => {
        previous = Date.now()
        timeout = null
        func.apply(context, args)
      }, wait);
    }
  }
}



// 完整解决方案
let throttle3 = function (func, wait, options) {
  let context, args, timeout
  let previous = 0   // 时间戳
  if (!options) options = {}

  let later = function () {
    previous = Date.now()
    timeout = null
    func.apply(context, args)
  }

  return function () {
    context = this
    args = arguments
    let current = Date.now()
    if (options.leading === false && !previous) previous = current
    else if (current - previous > wait) {
      // 第一次会直接执行
      if (timeout) {
        clearTimeout(timeout)
        timeout = null
      }
      func.apply(context, args)
      previous = current
    } else if (!timeout && options.trailing !== false) {
      // 最后一次会被执行
      timeout = setTimeout(later, wait);
    }
  }
}